package com.kinyx.framework.db.vo;

import java.lang.reflect.Field;

import javax.persistence.Id;
import javax.persistence.Transient;

import com.kinyx.framework.annotation.assist.Tester;
import com.kinyx.framework.db.defines.INamingStrategy;
import com.kinyx.framework.enums.impl.ErrorCode1;
import com.kinyx.framework.exception.KRuntimeException;
import com.kinyx.framework.reflect.KAnnotationUtils;
import com.kinyx.framework.reflect.KTypeConverter;
import com.kinyx.framework.utils.KStringUtils;

class MappingHandler {

	@Tester("com.kinyx.framework.db.vo.MappingHandler_Tester_load_table_name")
	static String load_table_name(final Class<?> entityClass, final INamingStrategy ns) {
		final String str1 = MappingHandlerHelper.Entity$name(entityClass);
		final String str2 = MappingHandlerHelper.Table$name(entityClass);
		final String str3 = KTypeConverter.convert(KAnnotationUtils.getValue(entityClass, "org.hibernate.annotations.Table", "appliesTo"), String.class);
		return KStringUtils.checkBlankAndCompare(str1, str2, str3, () -> {
			return ns.entityName2tableName(entityClass.getSimpleName());
		}, () -> {
			throw new KRuntimeException(ErrorCode1.CODE_ERROR_41).param("className", entityClass.getName()).param("str1", str1).param("str2", str2);
		}, () -> {
			throw new KRuntimeException(ErrorCode1.CODE_ERROR_42).param("className", entityClass.getName()).param("str1", str1).param("str3", str3);
		}, () -> {
			throw new KRuntimeException(ErrorCode1.CODE_ERROR_43).param("className", entityClass.getName()).param("str2", str2).param("str3", str3);
		});
	}

	static String load_table_alias(final Class<?> entityClass) {
		return KStringUtils.uncapitalize(entityClass.getSimpleName());
	}

	@Tester("com.kinyx.framework.db.vo.MappingHandler_Tester_isColumn")
	static boolean isColumn(final Field field) {
		return field.getAnnotation(Transient.class) == null;
	}

	@Tester("com.kinyx.framework.db.vo.MappingHandler_Tester_load_column_name")
	static String load_column_name(final Field mappedField, final INamingStrategy ns) {
		return KStringUtils.checkBlank(MappingHandlerHelper.Column$name(mappedField), () -> {
			return ns.fieldName2columnName(mappedField.getName());
		});
	}

	static boolean load_column_insertable(final Field mappedField) {
		final Boolean column$insertable = MappingHandlerHelper.Column$insertable(mappedField);
		if (load_column_primaryKey(mappedField)) {// 是主键
			if (column$insertable == null) {
				return true;
			}
			if (!column$insertable) {
				throw new KRuntimeException(ErrorCode1.CODE_ERROR_12).param("className", mappedField.getDeclaringClass().getName()).param("fieldName", mappedField.getName());
			}
		}
		return column$insertable == null ? true : column$insertable;
	}

	static boolean load_column_updatable(final Field mappedField) {
		final Boolean column$updatable = MappingHandlerHelper.Column$updatable(mappedField);
		if (load_column_primaryKey(mappedField)) {// 是主键
			if (column$updatable == null) {
				return false;
			}
			if (column$updatable) {
				throw new KRuntimeException(ErrorCode1.CODE_ERROR_13).param("className", mappedField.getDeclaringClass().getName()).param("fieldName", mappedField.getName());
			}
		}
		return column$updatable == null ? true : column$updatable;
	}

	@Tester("com.kinyx.framework.db.vo.MappingHandler_Tester_load_column_primaryKey")
	static boolean load_column_primaryKey(final Field mappedField) {
		return mappedField.getAnnotation(Id.class) != null;
	}

}
